//必须带done回调 执行完成调用
import { customAlphabet } from 'nanoid'
import jQuery from 'jquery'
import Actions from './index'
import trim from 'lodash/trim'
import isArray from 'lodash/isArray'
import isPlainObject from 'lodash/isPlainObject'
import { processingConstant, getActionData } from '@ve/utils/utils'
// import { ElMessage } from 'element-plus'
import { setTimeout } from 'core-js'
export default function logicJudge(params) {
  const { vm, module, action, additionalData, done, _task, _indexObj, eventName } = params
  // console.log('vm', vm)
  // console.log('action --------- 逻辑判断', action)
  // console.log('_task------------', _task)
  let callbackData = params.callbackData
  // console.log('additionalData -------- ', additionalData)

  // 如果有选择的动作数据 则取动作数据
  const dataSourseAction = action.extension.logicConfig.value.dataSourse
  if (dataSourseAction) {
    callbackData = getActionData(vm, vm.info._id, dataSourseAction)
  }
  console.log('逻辑判断数据 ============== ', callbackData)

  const addActionsFunc = (actions) => {
    let childTask = []
    actions.forEach((action) => {
      childTask.push((arg, done) => {
        _indexObj._index++
        callbackData = arg
        console.log('动作执行', action._id, `${vm?.info.name}-${eventName}`, action.name)
        try {
          Actions[action.event]({ vm, module, action, callbackData, additionalData, done, _task, _indexObj, eventName })
        } catch (e) {
          console.warn(e)
        }
      })
    })
    _task.splice(_indexObj._index + 1, 0, ...childTask)
  }

  let resolveDataList = [] // 判断成功的数据的集合（回调数据为数组时使用）
  let rejectDataList = [] // 判断失败的数据的集合（回调数据为数组时使用）

  if (isArray(callbackData)) {
    // 数组类型的回调数据则取数组中的每一项都进行判断
    let _taskFlag = true
    for (let index = 0; index < callbackData.length; index++) {
      let taskFlag = null
      if (process.env.VUE_APP_BuildProjectType === 'mobile' || vm.$store.state.diy.settings.mode === 'mobile') {
        taskFlag = pdaLogicJudgeFunc(callbackData[index])
      } else {
        taskFlag = logicJudgeFunc(callbackData[index])
      }

      if (!taskFlag) {
        // 条件不成立则添加当前项数据至失败列表
        rejectDataList.push(callbackData[index])
        // _taskFlag = false
        // break
      } else {
        // 条件成立则添加当前项数据至成功列表
        resolveDataList.push(callbackData[index])
      }
      console.log('resolveDataList ----------- ', resolveDataList)
      console.log('rejectDataList ----------- ', rejectDataList)
      // if ()
    }
    if (action.extension.logicConfig.value.executeResoveItem && !resolveDataList.length) {
      // 如果有配置失败继续执行成功项 但是没有成功项时 则不往下执行
      _taskFlag = false
    } else if (!action.extension.logicConfig.value.executeResoveItem && rejectDataList.length) {
      // 如果没有有配置失败继续执行成功项 但是有失败项时 则不往下执行
      _taskFlag = false
    }
    if (action.extension.logicConfig.value.rejectMessage && rejectDataList.length) {
      // 如果有配置失败消息提示并且有失败数据 则显示提示消息
      const message = action.extension.logicConfig.value.rejectMessage
      const staticList = message.split(/#{.*?}/gi)
      const variableList = message.match(/#{(.+?)\}/g)
      let messageContent = message
      if (variableList && variableList.length) {
        // 如果有配置变量 则先获取变量值
        variableList.forEach((variableItem, index) => {
          let variableContent = ''
          variableItem = trim(variableItem.slice(2, -1))
          // 遍历获取回调数据的每一项的变量值 然后做拼接
          let variableList = []
          rejectDataList.forEach((item) => {
            variableList.push(item[variableItem])
          })
          variableContent = variableList.join(' , ')
          staticList.splice(index * 2 + 1, 0, variableContent)
        })
        messageContent = staticList.join('')
      }
      setTimeout(() => {
        vm.$baseMessage(messageContent, 'error')
      })

      // ElMessage({
      //   showClose: true,
      //   message: messageContent,
      //   type: 'error',
      // })
    }
    if (_taskFlag) {
      // 条件成立 则添加分路事件进入事件队列 并进入下一步
      addActionsFunc(action.actions)
      // 添加子队列至主队列
      done(null, resolveDataList)
    } else {
      // 条件不成立 则不添加分路事件进事件队列 直接进入下一步
      // 添加条件不成立的else分支 添加else动作
      addActionsFunc(action.elseActions || [])
      done(null, callbackData)
    }
  } else {
    let taskFlag = null
    if (process.env.VUE_APP_BuildProjectType === 'mobile' || vm.$store.state.diy.settings.mode === 'mobile') {
      taskFlag = pdaLogicJudgeFunc(callbackData)
    } else {
      taskFlag = logicJudgeFunc(callbackData)
    }
    // const taskFlag = logicJudgeFunc(callbackData)
    if (taskFlag) {
      // 条件成立 则添加分路事件进入事件队列 并进入下一步
      addActionsFunc(action.actions)
      // 添加子队列至主队列
      done(null, callbackData)
    } else {
      // 条件不成立 则不添加分路事件进事件队列 直接进入下一步
      if (action.extension.logicConfig.value.rejectMessage) {
        // 如果有配置失败消息提示 则显示消息提示
        const message = action.extension.logicConfig.value.rejectMessage
        const staticList = message.split(/#{.*?}/gi)
        const variableList = message.match(/#{(.+?)\}/g)
        let messageContent = message
        if (variableList && variableList.length) {
          // 如果有配置变量 则先获取变量值
          variableList.forEach((variableItem, index) => {
            let variableContent = ''
            variableItem = trim(variableItem.slice(2, -1))
            variableContent = callbackData[variableItem]
            staticList.splice(index * 2 + 1, 0, variableContent)
          })
          messageContent = staticList.join('')
        }
        setTimeout(() => {
          vm.$baseMessage(messageContent, 'error')
        })
        // ElMessage({
        //   showClose: true,
        //   message: messageContent,
        //   dangerouslyUseHTMLString: true,
        //   type: 'error',
        // })
      }
      // 添加条件不成立的else分支 添加else动作
      addActionsFunc(action.elseActions || [])
      done(null, callbackData)
    }
  }

  function logicJudgeFunc(_callbackData) {
    let { type, field, conditionVal, conditionType, conditionState, layerId, tabId, tabPaneId } = action.extension.logicConfig.value
    // 如果条件值配置的为变量类型 则取变量值
    if (/{[^#{]+}/g.test(conditionVal)) {
      conditionVal = _callbackData[trim(conditionVal.substring(2, conditionVal.length - 1))]
    }
    const conditionList = action.extension.logicConfig.value.conditionList || []
    // 这里将全等改为模糊等，防止数据类型为数值时的判断错误
    conditionState = conditionState == '===' ? '==' : conditionState
    conditionState = conditionState == '!==' ? '!=' : conditionState
    let taskFlag = false
    if (type === 1) {
      // 执行请求成功判断
      if (_callbackData.code === '00000') {
        taskFlag = true
      }
    } else if (type === 2) {
      // 执行请求失败判断
      if (_callbackData.code && _callbackData.code !== '00000') {
        taskFlag = true
      }
    } else if (type === 5) {
      // 进行图层打开判断
      // 查找页面dom
      const layerDom = jQuery(`#layerPage_${layerId[0]}`)
      const _pane = layerDom.parents('.splitpanes__pane')[0]
      if (_pane && _pane.style.display !== 'none') taskFlag = true
    } else if (type === 3) {
      // 执行字段值判断
      const componentId = (num) => {
        const nanoid = customAlphabet('abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMN', num)
        return nanoid()
      }
      window.cacheObj = {}
      const b = componentId(6)
      const d = componentId(6)
      if (field.indexOf('->') !== -1) {
        const fieldList = field.split('->')
        window.cacheObj[b] = _callbackData
        fieldList.forEach((fieldItem) => {
          // 如果没有后续值则不继续往下取值
          if (window.cacheObj[b][trim(fieldItem)] === undefined) return
          window.cacheObj[b] = window.cacheObj[b][trim(fieldItem)]
        })
      } else {
        // 对条件值做常量转化
        if (field !== processingConstant(vm, field)) {
          window.cacheObj[b] = processingConstant(vm, field)
        } else {
          window.cacheObj[b] = _callbackData[field] // 缓存条件值
        }
      }
      // 如果值为undefined且判断类型为 ‘值未定义’
      if (window.cacheObj[b] === undefined && conditionState === 'valueIsUndefined') {
        return true
      }
      // 如果拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
      if (isPlainObject(window.cacheObj[b]) || window.cacheObj[b] === undefined) {
        // done(null, callbackData)
        return false
      }
      // 如果拿到的值是null则重置为空字符串 防止比较值长度时抛错
      if (window.cacheObj[b] === null) window.cacheObj[b] = ''
      window.cacheObj[d] = processingConstant(vm, conditionVal) // 缓存判断值
      if (conditionState === '>' || conditionState === '<') {
        // 如果比较的是值的大于小于 则将值转化为数值类型
        if (conditionType === 'value') {
          // 如果比较的是值 则将获取到的值转化为数值类型
          window.cacheObj[b] = Number(window.cacheObj[b])
        }
        window.cacheObj[d] = Number(window.cacheObj[d])
      }
      let conditionStr = ''
      if (conditionType === 'value') {
        conditionStr += `cacheObj.${b} ${conditionState} cacheObj.${d}`
      } else if (conditionType === 'valueLength') {
        conditionStr += `cacheObj.${b}.length ${conditionState} cacheObj.${d}`
      }
      let flag = false
      console.log('conditionStr -----', conditionStr)
      console.log('window.cacheObj -----', window.cacheObj)
      try {
        // 执行字符串
        flag = Function('"use strict";return (' + conditionStr + ')')()
      } catch (error) {
        console.log('执行条件error', error)
        flag = false
      }
      if (flag) {
        taskFlag = true
      }
    } else if (type === 4) {
      // 执行多条件值判断
      let componentId = (num) => {
        const nanoid = customAlphabet('abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMN', num)
        return nanoid()
      }
      let conditionStr = ''
      window.cacheObj = {}
      let notFindVal = false
      // 计算条件是否满足
      conditionList.forEach((item, index) => {
        const b = componentId(6)
        const d = componentId(6)
        if (item.condition.field.indexOf('->') !== -1) {
          const fieldList = item.condition.field.split('->')
          window.cacheObj[b] = _callbackData
          fieldList.forEach((fieldItem) => {
            // 如果没有后续值则不继续往下取值
            if (window.cacheObj[b][trim(fieldItem)] === undefined) return
            window.cacheObj[b] = window.cacheObj[b][trim(fieldItem)]
          })
        } else {
          window.cacheObj[b] = _callbackData[item.condition.field] // 缓存条件值
        }
        // 如果拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
        if (isPlainObject(window.cacheObj[b]) || window.cacheObj[b] === undefined) {
          notFindVal = true
          return
        }
        // 如果条件值配置的为变量类型 则取变量值
        let conditionValue = item.condition.val
        if (/{[^#{]+}/g.test(conditionValue)) {
          conditionValue = _callbackData[trim(conditionValue.substring(2, conditionValue.length - 1))]
        }
        window.cacheObj[d] = processingConstant(vm, conditionValue)
        if (index) {
          // 从第二个条件开始 拼接条件的连接类型
          if (item.condition.type === 'value') {
            // 如果判断的是值，则直接对值进行判断
            conditionStr += ` ${item.connectType} cacheObj.${b} ${item.condition.state} cacheObj.${d}`
          } else if (item.condition.type === 'valueLength') {
            // 如果判断的是值长度 则取值长度进行判断
            conditionStr += ` ${item.connectType} cacheObj.${b}.length ${item.condition.state} cacheObj.${d}`
          }
        } else {
          if (item.condition.type === 'value') {
            conditionStr += ` cacheObj.${b} ${item.condition.state} cacheObj.${d}`
          } else if (item.condition.type === 'valueLength') {
            conditionStr += ` cacheObj.${b}.length ${item.condition.state} cacheObj.${d}`
          }
        }
      })
      // 如果有其中一个判断拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
      if (notFindVal) {
        return false
      }
      let flag = false
      try {
        // 执行字符串
        flag = Function('"use strict";return (' + conditionStr + ')')()
      } catch (error) {
        console.log('error', error)
        flag = false
      }
      if (flag) {
        taskFlag = true
      }
    } else if (type === 6) {
      // Tab页是否激活判断
      const tabModule = vm.vuiComponents[tabId[0]]?.self
      if (tabModule && tabModule.activeName === tabPaneId) taskFlag = true
    }

    // console.log('_indexObj --------------- ', _indexObj)
    // console.log('taskFlag --------- ', taskFlag)
    return taskFlag
  }

  function pdaLogicJudgeFunc(_callbackData) {
    console.log('_callbackData', _callbackData)
    let { type, field, conditionVal, conditionType, conditionState, compareField } = action.extension.logicConfig.value
    console.log('compareField', compareField, window)
    // 如果条件值配置的为变量类型 则取变量值
    if (/{[^#{]+}/g.test(conditionVal)) {
      conditionVal = _callbackData[trim(conditionVal.substring(2, conditionVal.length - 1))]
    }
    const conditionList = action.extension.logicConfig.value.conditionList || []
    // 这里将全等改为模糊等，防止数据类型为数值时的判断错误
    conditionState = conditionState == '===' ? '==' : conditionState
    conditionState = conditionState == '!==' ? '!=' : conditionState
    let taskFlag = false
    if (type === 1) {
      // 执行请求成功判断
      if (_callbackData.code === '00000') {
        taskFlag = true
      }
    } else if (type === 2) {
      // 执行请求失败判断
      if (_callbackData.code && _callbackData.code !== '00000') {
        taskFlag = true
      }
    } else if (type === 3) {
      // 执行字段值判断
      const componentId = (num) => {
        const nanoid = customAlphabet('abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMN', num)
        return nanoid()
      }
      window.cacheObj = {}
      const b = componentId(6)
      const d = componentId(6)
      const f = componentId(6)
      if (field.indexOf('->') !== -1) {
        const fieldList = field.split('->')
        window.cacheObj[b] = _callbackData
        fieldList.forEach((fieldItem) => {
          // 如果没有后续值则不继续往下取值
          if (window.cacheObj[b][trim(fieldItem)] === undefined) return
          window.cacheObj[b] = window.cacheObj[b][trim(fieldItem)]
        })
      } else {
        window.cacheObj[b] = _callbackData[field] // 缓存条件值
      }
      // if (compareField.indexOf('->') !== -1) {
      //   const compareFieldList = compareField.split('->')
      //   window.cacheObj[b] = _callbackData
      //   compareFieldList.forEach((fieldItem) => {
      //     console.log('fieldItem', fieldItem)
      //     if (window.cacheObj[b][trim(fieldItem)] === undefined) return
      //     window.cacheObj[b] = window.cacheObj[b][trim(fieldItem)]
      //   })
      // } else {
      window.cacheObj[f] = _callbackData[compareField] // 缓存条件值
      console.log('_callbackData[compareField]', window.cacheObj, _callbackData[compareField])
      // }

      // 如果拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
      if (isPlainObject(window.cacheObj[b]) || window.cacheObj[b] === undefined) {
        // done(null, callbackData)
        return false
      }
      // 如果拿到的值是null则重置为空字符串 防止比较值长度时抛错
      if (window.cacheObj[b] === null) window.cacheObj[b] = ''
      window.cacheObj[d] = processingConstant(vm, conditionVal) // 缓存判断值
      let conditionStr = ''
      if (conditionType === 'value' && window.cacheObj[d] != '') {
        conditionStr += `cacheObj.${b} ${conditionState} cacheObj.${d}`
      } else if (conditionType === 'value' && window.cacheObj[d] == '') {
        conditionStr += `cacheObj.${b} ${conditionState} cacheObj.${f}`
      } else if (conditionType === 'valueLength' && window.cacheObj[d] != '') {
        conditionStr += `cacheObj.${b}.length ${conditionState} cacheObj.${d}`
      } else if (conditionType === 'valueLength' && window.cacheObj[d] == '') {
        conditionStr += `cacheObj.${b}.length ${conditionState} cacheObj.${f}.length`
      }
      console.log('---conditionStr----运行的字符串', conditionStr)
      let flag = false
      try {
        // 执行字符串
        console.log('进了 try')
        flag = Function('"use strict";return (' + conditionStr + ')')()
        console.log('第一次flag ====== ', flag)
        flag = eval(conditionStr)
        console.log('第二次flag ====== ', flag)
      } catch (error) {
        console.log('执行条件error', error)
        flag = false
      }
      console.log('外面的 flag', flag)
      if (flag) {
        taskFlag = true
      }
    } else if (type === 4) {
      // 执行多条件值判断
      let componentId = (num) => {
        const nanoid = customAlphabet('abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMN', num)
        return nanoid()
      }
      let conditionStr = ''
      window.cacheObj = {}
      let notFindVal = false
      // 计算条件是否满足

      conditionList.forEach((item, index) => {
        const b = componentId(6)
        const d = componentId(6)
        if (item.condition.field.indexOf('->') !== -1) {
          const fieldList = item.condition.field.split('->')
          window.cacheObj[b] = _callbackData
          fieldList.forEach((fieldItem) => {
            // 如果没有后续值则不继续往下取值
            if (window.cacheObj[b][trim(fieldItem)] === undefined) return
            window.cacheObj[b] = window.cacheObj[b][trim(fieldItem)]
          })
        } else {
          window.cacheObj[b] = _callbackData[item.condition.field] // 缓存条件值
        }
        // 如果拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
        if (isPlainObject(window.cacheObj[b]) || window.cacheObj[b] === undefined) {
          notFindVal = true
          return
        }
        // 如果条件值配置的为变量类型 则取变量值
        let conditionValue = item.condition.val
        if (/{[^#{]+}/g.test(conditionValue)) {
          conditionValue = _callbackData[trim(conditionValue.substring(2, conditionValue.length - 1))]
        }
        window.cacheObj[d] = processingConstant(vm, conditionValue)
        console.log('db', window.cacheObj, conditionVal)
        if (index) {
          // 从第二个条件开始 拼接条件的连接类型
          if (item.condition.type === 'value') {
            // 如果判断的是值，则直接对值进行判断
            conditionStr += ` ${item.connectType} cacheObj.${b} ${item.condition.state} cacheObj.${d}`
          } else if (item.condition.type === 'valueLength') {
            // 如果判断的是值长度 则取值长度进行判断
            conditionStr += ` ${item.connectType} cacheObj.${b}.length ${item.condition.state} cacheObj.${d}`
          }
        } else {
          if (item.condition.type === 'value') {
            conditionStr += ` cacheObj.${b} ${item.condition.state} cacheObj.${d}`
          } else if (item.condition.type === 'valueLength') {
            conditionStr += ` cacheObj.${b}.length ${item.condition.state} cacheObj.${d}`
          }
        }
      })
      console.log('1-----111----111', conditionStr)
      // 如果有其中一个判断拿到的值是对象或者undefined 则代表直接判断失败（避免错误的不等于判断）
      if (notFindVal) {
        return false
      }
      let flag = false
      try {
        // 执行字符串
        flag = Function('"use strict";return (' + conditionStr + ')')()
      } catch (error) {
        console.log('error', error)
        flag = false
      }
      if (flag) {
        taskFlag = true
      }
    }

    // console.log('_indexObj --------------- ', _indexObj)
    // console.log('taskFlag --------- ', taskFlag)
    return taskFlag
  }
}
